package com.hccl.sluentities;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.SimpleTimeZone;

import entities.Reply;
import entities.Transition;
import org.bson.types.ObjectId;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.annotations.*;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.UpdateOperations;
import org.springframework.beans.factory.annotation.Autowired;

@Entity(value = "menus", noClassnameStored = true)
public class NavigationEntity {

    @Autowired
    private Datastore datastore;
    @Id
    protected ObjectId id;
    protected List<Reply> reply;
    @Reference(idOnly=true,lazy=true)
    private NavigationEntity parent;
    @Reference(idOnly=true,lazy=true)
    private List<NavigationEntity> children = new ArrayList<NavigationEntity>();
    protected String query;
    protected List<Transition> transitions = new ArrayList<Transition>();
    @Reference(idOnly=true,lazy=true)
    protected List<GrammarVariableEntity> params=new ArrayList<GrammarVariableEntity>();
    protected String init_process;
    protected String name;
    protected int level;//代表什么？
    @Reference(idOnly=true,lazy=true)
    protected List<GrammarRuleEntity> rules = new ArrayList<GrammarRuleEntity>();
    protected int replytype;//0：静态回复reply；1：动态回复query
    protected List<String> corpus = new ArrayList<String>();;

    public List<String> getCorpus() {
        return corpus;
    }

    public void setCorpus(List<String> corpus) {
        this.corpus = corpus;
    }

    public Reply getHelpReply() {
        return helpReply;
    }

    public void setHelpReply(Reply helpReply) {
        this.helpReply = helpReply;
    }

    protected Reply helpReply;

    protected NoMatchOrInput noMatch;

    protected NoMatchOrInput noInput;

    public NoMatchOrInput getNoMatch() {
        return noMatch;
    }

    public void setNoMatch(NoMatchOrInput noMatch) {
        this.noMatch = noMatch;
    }

    public NoMatchOrInput getNoInput() {
        return noInput;
    }

    public void setNoInput(NoMatchOrInput noInput) {
        this.noInput = noInput;
    }

    public ObjectId getId() {
        return id;
    }

    public void setId(ObjectId id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public NavigationEntity getParent() {
        return parent;
    }

    public void setParent(NavigationEntity parent) {
        this.parent = parent;
    }

    public List<NavigationEntity> getChildren() {
        return children;
    }

    public List<Reply> getReply() {
        return reply;
    }

    public void setReply(List<Reply> reply) {
        this.reply = reply;
    }

    public String  getQuery(){return query;}

    public void setQuery(String query){this.query=query;}

    public List<GrammarRuleEntity> getRules() {
        return rules;
    }

    public void setRules(List<GrammarRuleEntity> rules) {
        this.rules = rules;
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public List<GrammarVariableEntity> getParams(){return this.params;}

    public void setParams(List<GrammarVariableEntity> list){this.params=list;}

    public int getReplytype(){return this.replytype;}

    public void setReplytype(int rt){this.replytype=rt;}

    public List<Transition> getTransitions(){return transitions;}

    public void setTransitions(List<Transition> list){this.transitions=list;}

    public String getInit_process() {
        return init_process;
    }

    public void setInit_process(String init_process) {
        this.init_process = init_process;
    }

    @PrePersist
    public void prePersist() {

        if(null==parent){
            level = 1;
        }
        else{
            level = parent.getLevel()+1;
        }
    }

    @PostPersist
    public void postPersist() {

        if(null!=parent){
            for (NavigationEntity c : parent.getChildren()){
                if(c.getId().equals(id)){
                    return;
                }
            }
            UpdateOperations<NavigationEntity> ops = datastore
                    .createUpdateOperations(NavigationEntity.class).add("children",
                            getId(),false);
            Query<NavigationEntity> updateQuery = datastore
                    .createQuery(NavigationEntity.class).field("_id").equal(parent.getId());
            datastore.update(updateQuery, ops);
            parent.getChildren().add(this);
        }
    }

    public NavigationEntity remove(){
        return remove(true);
    }

    public NavigationEntity remove(boolean updateParent){

        if(updateParent&&parent!=null){
            Iterator<NavigationEntity> it = parent.getChildren().iterator();
            while (it.hasNext()){
                if(it.next().getId().equals(id)){
                    it.remove();
                }
            }
            datastore.save(parent);
        }
        for (GrammarRuleEntity rule:rules){
            datastore.delete(rule);
        }
        for (NavigationEntity child:children){
            datastore.delete(child.remove(false));
        }
        return this;
    }
}